/****************************************************************
 *  This file created by writerB.php on 03/20/2007 at 20:43:22  *
 ****************************************************************
 *  writerB.php created by Tonk (tonk@ctonk.com) in 2007        *
 ****************************************************************
 *                 General Document Information
 *
 *  File Name: object.cpp
 *  Class Name: Object
 *  Data members: 8
 *  Notes:
 ****************************************************************/

#include <iostream>
#include "combined.h"
#include "definitions.h"
#include "log.h"
#include "object_derived.h"
#include "stringutil.h"


/////////////////////////////////////////////  BASE OBJECT  //////////////////////////////////////////
int Object::numObjects = 0;
int Object::objectIndex = 0;


// Default constructor...
Object::Object() {
	setObjectID( ++objectIndex );
	setVnum( 0 );
	setType( OT_ERROR );
	setWeight( 0 );
	setFlags( 0 );
	// Increment the object count...
	numObjects++;
}

// Additional constructors...

// Copy constructor (Doesn't change _ObjectID)...
Object::Object( const Object& ref ) {
	setObjectID( ++objectIndex );
	setVnum( ref.getVnum() );
	setType( ref.getType() );
	setWeight( ref.getWeight() );
	setFlags( ref.getFlags() );
	setName( ref.getName() );
	setShortDesc( ref.getShortDesc() );
	setLongDesc( ref.getLongDesc() );
	setFullDesc( ref.getFullDesc() );
	// Increment the object count...
	numObjects++;
}

// Destructor...
Object::~Object() {
	// Decrement the object count...
	numObjects--;
}

// Assignment operator (Doesn't change _ObjectID)...
Object& Object::operator = ( const Object& ref ) {
	setVnum( ref.getVnum() );
	setType( ref.getType() );
	setWeight( ref.getWeight() );
	setFlags( ref.getFlags() );
	setName( ref.getName() );
	setShortDesc( ref.getShortDesc() );
	setLongDesc( ref.getLongDesc() );
	setFullDesc( ref.getFullDesc() );
	return *this;
}

// Equality operator (Compares _vnum)...
bool Object::operator == ( const Object& ref ) const {
	return	( getVnum() == ref.getVnum() );
}

// Inequality operator (Compares _vnum)...
bool Object::operator != ( const Object& ref ) const {
	return	( getVnum() != ref.getVnum() );
}

// Less than operator (Compares _vnum)...
bool Object::operator < ( const Object& ref ) const {
	return ( getVnum() < ref.getVnum() );
}

// Greater than operator (Compares _vnum)...
bool Object::operator > ( const Object& ref ) const {
	return ( getVnum() > ref.getVnum() );
}

// Protected Methods...
void Object::setObjectID( const int& ObjectID ) { // protected
	_ObjectID = ObjectID;
}

std::string Object::objectDisplay( const std::string& subTypeDisplay ) { // protected
	std::string buf;

	buf << "{Cvnum:{x " << getVnum() << "\n\r";
	buf << "{Ctype:{x " << Object::type2string( getType() ) << "\n\r";
	buf << "{Cflags:{x " << getFlags() << "\n\r";
	buf << "{Ckeywords:{x " << getName() << "\n\r";
	buf << "{Cshort:{x " << getShortDesc() << "\n\r";
	buf << "{Clong:{x " << getLongDesc() << "\n\r";
	buf << subTypeDisplay;
	buf << "{CDescription:{x " << getFullDesc() << "\n\r";

	return buf;
}

// Public accessor methods...
int Object::getObjectID( void ) const {
	return _ObjectID;
}

void Object::setVnum( const unsigned& vnum ) {
	_vnum = vnum;
	return;
}

unsigned Object::getVnum( void ) const {
	return _vnum;
}

void Object::setType( const OBJECT_TYPE& type ) {
	// _type is non-negative...
	_type = ( type >= OT_ERROR ) ? type : OT_ERROR;
	return;
}

OBJECT_TYPE Object::getType( void ) const {
	return _type;
}

void Object::setWeight( const int& weight ) {
	// _weight is non-negative...
	_weight = ( weight >= 0 ) ? weight : 0;
	return;
}

int Object::getWeight( void ) const {
	return _weight;
}

void Object::setFlags( const int& flags ) {
	_flags = flags;
	return;
}

int Object::getFlags( void ) const {
	return _flags;
}

void Object::setName( const std::string& name ) {
	_name = name;
	return;
}

std::string Object::getName( void ) const {
	return _name;
}

void Object::setShortDesc( const std::string& shortDesc ) {
	_shortDesc = shortDesc;
	return;
}

std::string Object::getShortDesc( void ) const {
	return _shortDesc;
}

void Object::setLongDesc( const std::string& longDesc ) {
	_longDesc = longDesc;
	return;
}

std::string Object::getLongDesc( void ) const {
	return _longDesc;
}

void Object::setFullDesc( const std::string& fullDesc ) {
	_fullDesc = fullDesc;
	return;
}

std::string Object::getFullDesc( void ) const {
	return _fullDesc;
}

std::string* Object::getFullDescP( void ) {
	return &_fullDesc;
}

// General methods...
void Object::oSave( std::ostream& write ) {
	write << "\n**OBJECT\n";
	write << getVnum() << ' ' << type2string( getType() ) << ' ' << getFlags() << ' ' << getName() << '\n';
	write << getShortDesc() << '\n' << getLongDesc() << '\n' << getFullDesc() << "$\n";

	return;
}

void Object::copyBaseData( const Object& ref ) {

	setVnum( ref.getVnum() );
	setType( ref.getType() );
	setFlags( ref.getFlags() );
	setName( ref.getName() );
	setShortDesc( ref.getShortDesc() );
	setLongDesc( ref.getLongDesc() );
	setFullDesc( ref.getFullDesc() );

	return;
}

// Static methods...
std::string Object::type2string( const OBJECT_TYPE& type ) { // static
	switch ( type ) {
		case ACCESSORY:	return "accessory";
		case ARMOR:		return "armor";
		case BODY_PART:	return "body_part";
		case CLOTHING:	return "clothing";
		case COIN:		return "coin";
		case CONTAINER:	return "container";
		case DRINK:		return "drink";
		case FOOD:		return "food";
		case FURNITURE:	return "furniture";
		case JEWELRY:	return "jewelry";
		case SCROLL:	return "scroll";
		case TRASH:		return "trash";
		case WAND:		return "wand";
		case WEAPON:	return "weapon";
		default:
			std::string message;
			message	<< "Object::type2string() default hit in " << __FILE__ << " line " << __LINE__;
			log( message, SERVER );
			return "ERROR";
	}
}

OBJECT_TYPE Object::string2type( const std::string& type ) { // static
	if ( type == "accessory" )
		return ACCESSORY;
	else if ( type == "armor" )
		return ARMOR;
	else if ( type == "body_part" )
		return BODY_PART;
	else if ( type == "clothing" )
		return CLOTHING;
	else if ( type == "coin" )
		return COIN;
	else if ( type == "container" )
		return CONTAINER;
	else if ( type == "drink" )
		return DRINK;
	else if ( type == "food" )
		return FOOD;
	else if ( type == "furniture" )
		return FURNITURE;
	else if ( type == "jewelry" )
		return JEWELRY;
	else if ( type == "scroll" )
		return SCROLL;
	else if ( type == "trash" )
		return TRASH;
	else if ( type == "wand" )
		return WAND;
	else if ( type == "weapon" )
		return WEAPON;
	else 
		return OT_ERROR;
}

Object* Object::getNewObject( const OBJECT_TYPE& type, Object* object_in ) {
	Object* object_out = NULL;
	switch ( type ) {
		case ACCESSORY:	object_out = new Accessory; break;
		case ARMOR:		object_out = new Armor; break;
		case BODY_PART:	object_out = new Body_Part; break;
		case CLOTHING:	object_out = new Clothing; break;
		case COIN:		object_out = new Coin; break;
		case CONTAINER:	object_out = new Container; break;
		case DRINK:		object_out = new Drink; break;
		case FOOD:		object_out = new Food; break;
		case FURNITURE:	object_out = new Furniture; break;
		case JEWELRY:	object_out = new Jewelry; break;
		case SCROLL:	object_out = new Scroll; break;
		case TRASH:		object_out = new Trash; break;
		case WAND:		object_out = new Wand; break;
		case WEAPON:	object_out = new Weapon; break;
		default:
			std::string message;
			message	<< "Object::getNewObject() default hit in " << __FILE__ << " line " << __LINE__;
			log( message, SERVER );
			return NULL;
	}

	if ( object_in )
		object_out->copy( object_in );

	return object_out;
}

std::ostream& operator << ( std::ostream& write, Object& object ) {
	object.save( write );
	return write;
}

std::ostream& operator << ( std::ostream& write, Object* object ) {
	return ( write << *object );
}

/////////////////////////////////////////////  END BASE OBJECT  //////////////////////////////////////////

/////////////////////////////////////////// ACCESSORY OBJECT ///////////////////////////////////////////
Accessory::Accessory(): Object() { }

Accessory::Accessory( Accessory& ref ): Object( ref ) { }

Accessory::~Accessory() { }

Accessory& Accessory::operator = ( Accessory& ref ) {
	copyBaseData( ref );

	return *this;
}

std::string Accessory::display() {
	std::string buf;

	buf << objectDisplay( buf );

	return buf;
}

void Accessory::copy( Object* object_in ) {

	return;
}

void Accessory::load( std::istream& read ) {

	return;
}

void Accessory::save( std::ostream& write ) {
	oSave( write );

	write << "\n\n";
	return;
}

/////////////////////////////////////////// ARMOR OBJECT ///////////////////////////////////////////
Armor::Armor(): Object() { }

Armor::Armor( Armor& ref ): Object( ref ) { }

Armor::~Armor() { }

Armor& Armor::operator = ( Armor& it ) {
	copyBaseData( it );

	return *this;
}

std::string Armor::display() {
	std::string buf;

	buf << objectDisplay( buf );

	return buf;
}

void Armor::copy( Object* object_in ) {

	return;
}

void Armor::load( std::istream& read ) {

	return;
}

void Armor::save( std::ostream& write ) {
	oSave( write );

	write << "\n\n";
	return;
}

/////////////////////////////////////////// BODY_PART OBJECT ///////////////////////////////////////////
Body_Part::Body_Part(): Object() { }

Body_Part::Body_Part( Body_Part& ref ): Object( ref ) { }

Body_Part::~Body_Part() { }

Body_Part& Body_Part::operator = ( Body_Part& it ) {
	copyBaseData( it );

	return *this;
}

std::string Body_Part::display() {
	std::string buf;

	buf << objectDisplay( buf );

	return buf;
}

void Body_Part::copy( Object* object_in ) {

	return;
}

void Body_Part::load( std::istream& read ) {

	return;
}

void Body_Part::save( std::ostream& write ) {
	oSave( write );

	write << "\n\n";
	return;
}

/////////////////////////////////////////// CLOTHING OBJECT ///////////////////////////////////////////
Clothing::Clothing(): Object() { }

Clothing::Clothing( Clothing& ref ): Object( ref ) { }

Clothing::~Clothing() { }

Clothing& Clothing::operator = ( Clothing& it ) {
	copyBaseData( it );

	return *this;
}

std::string Clothing::display() {
	std::string buf;

	buf << objectDisplay( buf );

	return buf;
}

void Clothing::copy( Object* object_in ) {

	return;
}

void Clothing::load( std::istream& read ) {

	return;
}

void Clothing::save( std::ostream& write ) {
	oSave( write );

	write << "\n\n";
	return;
}

/////////////////////////////////////////// COIN OBJECT ///////////////////////////////////////////
Coin::Coin(): Object() { }

Coin::Coin( Coin& ref ): Object( ref ) { }

Coin::~Coin() { }

Coin& Coin::operator = ( Coin& it ) {
	copyBaseData( it );

	return *this;
}

std::string Coin::display() {
	std::string buf;

	buf << objectDisplay( buf );

	return buf;
}

void Coin::copy( Object* object_in ) {

	return;
}

void Coin::load( std::istream& read ) {

	return;
}

void Coin::save( std::ostream& write ) {
	oSave( write );

	write << "\n\n";
	return;
}

/////////////////////////////////////////// CONTAINER OBJECT ///////////////////////////////////////////
Container::Container(): Object() { }

Container::Container( Container& ref ): Object( ref ) { }

Container::~Container() { }

Container& Container::operator = ( Container& it ) {
	copyBaseData( it );

	return *this;
}

std::string Container::display() {
	std::string buf;

	buf << objectDisplay( buf );

	return buf;
}

void Container::copy( Object* object_in ) {

	return;
}

void Container::load( std::istream& read ) {

	return;
}

void Container::save( std::ostream& write ) {
	oSave( write );

	write << "\n\n";
	return;
}

/////////////////////////////////////////// DRINK OBJECT ///////////////////////////////////////////
Drink::Drink(): Object() { }

Drink::Drink( Drink& ref ): Object( ref ) { }

Drink::~Drink() { }

Drink& Drink::operator = ( Drink& it ) {
	copyBaseData( it );

	return *this;
}

std::string Drink::display() {
	std::string buf;

	buf << objectDisplay( buf );

	return buf;
}

void Drink::copy( Object* object_in ) {

	return;
}

void Drink::load( std::istream& read ) {

	return;
}

void Drink::save( std::ostream& write ) {
	oSave( write );

	write << "\n\n";
	return;
}

/////////////////////////////////////////// FOOD OBJECT ///////////////////////////////////////////
Food::Food(): Object() { }

Food::Food( Food& ref ): Object( ref ) { }

Food::~Food() { }

Food& Food::operator = ( Food& it ) {
	copyBaseData( it );

	return *this;
}

std::string Food::display() {
	std::string buf;

	buf << objectDisplay( buf );

	return buf;
}

void Food::copy( Object* object_in ) {

	return;
}

void Food::load( std::istream& read ) {

	return;
}

void Food::save( std::ostream& write ) {
	oSave( write );

	write << "\n\n";
	return;
}

/////////////////////////////////////////// FURNITURE OBJECT ///////////////////////////////////////////
Furniture::Furniture(): Object() { }

Furniture::Furniture( Furniture& ref ): Object( ref ) { }

Furniture::~Furniture() { }

Furniture& Furniture::operator = ( Furniture& it ) {
	copyBaseData( it );

	return *this;
}

std::string Furniture::display() {
	std::string buf;

	buf << objectDisplay( buf );

	return buf;
}

void Furniture::copy( Object* object_in ) {

	return;
}

void Furniture::load( std::istream& read ) {

	return;
}

void Furniture::save( std::ostream& write ) {
	oSave( write );

	write << "\n\n";
	return;
}

/////////////////////////////////////////// JEWELRY OBJECT ///////////////////////////////////////////
Jewelry::Jewelry(): Object() { }

Jewelry::Jewelry( Jewelry& ref ): Object( ref ) { }

Jewelry::~Jewelry() { }

Jewelry& Jewelry::operator = ( Jewelry& it ) {
	copyBaseData( it );

	return *this;
}

std::string Jewelry::display() {
	std::string buf;

	buf << objectDisplay( buf );

	return buf;
}

void Jewelry::copy( Object* object_in ) {

	return;
}

void Jewelry::load( std::istream& read ) {

	return;
}

void Jewelry::save( std::ostream& write ) {
	oSave( write );

	write << "\n\n";
	return;
}

/////////////////////////////////////////// SCROLL OBJECT ///////////////////////////////////////////
Scroll::Scroll(): Object() { }

Scroll::Scroll( Scroll& ref ): Object( ref ) { }

Scroll::~Scroll() { }

Scroll& Scroll::operator = ( Scroll& it ) {
	copyBaseData( it );

	return *this;
}

std::string Scroll::display() {
	std::string buf;

	buf << objectDisplay( buf );

	return buf;
}

void Scroll::copy( Object* object_in ) {

	return;
}

void Scroll::load( std::istream& read ) {

	return;
}

void Scroll::save( std::ostream& write ) {
	oSave( write );

	write << "\n\n";
	return;
}

/////////////////////////////////////////// TRASH OBJECT ///////////////////////////////////////////
Trash::Trash(): Object() { }

Trash::Trash( Trash& ref ): Object( ref ) { }

Trash::~Trash() { }

Trash& Trash::operator = ( Trash& it ) {
	copyBaseData( it );

	return *this;
}

std::string Trash::display() {
	std::string buf;

	buf << objectDisplay( buf );

	return buf;
}

void Trash::copy( Object* object_in ) {

	return;
}

void Trash::load( std::istream& read ) {

	return;
}

void Trash::save( std::ostream& write ) {
	oSave( write );

	write << "\n\n";
	return;
}

/////////////////////////////////////////// WAND OBJECT ///////////////////////////////////////////
Wand::Wand(): Object() { }

Wand::Wand( Wand& ref ): Object( ref ) { }

Wand::~Wand() { }

Wand& Wand::operator = ( Wand& it ) {
	copyBaseData( it );

	return *this;
}

std::string Wand::display() {
	std::string buf;

	buf << objectDisplay( buf );

	return buf;
}

void Wand::copy( Object* object_in ) {

	return;
}

void Wand::load( std::istream& read ) {

	return;
}

void Wand::save( std::ostream& write ) {
	oSave( write );

	write << "\n\n";
	return;
}

/////////////////////////////////////////// WEAPON OBJECT ///////////////////////////////////////////
Weapon::Weapon(): Object() { }

Weapon::Weapon( Weapon& ref ): Object( ref ) { }

Weapon::~Weapon() { }

Weapon& Weapon::operator = ( Weapon& it ) {
	copyBaseData( it );

	return *this;
}

std::string Weapon::display() {
	std::string buf;

	buf << objectDisplay( buf );

	return buf;
}

void Weapon::copy( Object* object_in ) {

	return;
}

void Weapon::load( std::istream& read ) {

	return;
}

void Weapon::save( std::ostream& write ) {
	oSave( write );

	write << "\n\n";
	return;
}


